﻿using System;
using System.Collections;
using System.Data.Common;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;

namespace 账号管理
{
    /// <summary>
    /// DbCommand扩展
    /// </summary>
    public static class Extension
    {
        /// <summary>
        /// 设置参数
        /// </summary>
        /// <param name="cmd">CMD执行语句</param>
        /// <param name="parameters">参数列表</param>
        public static void SetParameters(this DbCommand cmd, object parameters)
        {
            cmd.Parameters.Clear();

            if (parameters == null)
                return;

            if (parameters is IList)
            {
                var listed = (IList)parameters;
                for (var i = 0; i < listed.Count; i++)
                {
                    AddParameter(cmd, string.Format("@{0}", i), listed[i]);
                }
            }
            else
            {
                var t = parameters.GetType();
                var parameterInfos = t.GetProperties();
                foreach (var pi in parameterInfos)
                {
                    AddParameter(cmd, pi.Name, pi.GetValue(parameters, null));
                }
            }
        }
        /// <summary>
        /// 添加参数
        /// </summary>
        /// <param name="cmd">cmd执行命令</param>
        /// <param name="name">参数名称</param>
        /// <param name="value">参数值</param>
        private static void AddParameter(DbCommand cmd, string name, object value)
        {
            var p = cmd.CreateParameter();
            p.ParameterName = name;
            p.Value = value ?? DBNull.Value;
            cmd.Parameters.Add(p);
        }
        /// <summary>
        /// 通用对象转换 支持枚举，?类型
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="obj">对象</param>
        /// <param name="defaultValue">默认值</param>
        /// <returns>返回指定类型的对象</returns>
        public static T GetValue<T>(this object obj, T defaultValue)
        {
            if (obj == null || obj == DBNull.Value)
            {
                return defaultValue;
            }
            else if (typeof(T).IsEnum)
            {
                return (T)Enum.ToObject(typeof(T), obj);
            }
            else
            {
                if (!typeof(T).IsGenericType)
                {
                    return (T)Convert.ChangeType(obj, typeof(T));
                }
                else
                {
                    Type genericTypeDefinition = typeof(T).GetGenericTypeDefinition();
                    if (genericTypeDefinition == typeof(Nullable<>))
                    {
                        return (T)Convert.ChangeType(obj, Nullable.GetUnderlyingType(typeof(T)));
                    }
                    else
                    {
                        return defaultValue;
                    }
                }
            }
        }
        /// <summary>
        /// 判断对象是否为空
        /// </summary>
        /// <param name="obj">对象</param>
        /// <returns></returns>
        public static bool IsNullOrEmpty(this object obj)
        {
            if (obj == null || obj == DBNull.Value) return true;

            return false;
        }
        public static byte[] ReadAllBinary(this Stream Input)
        {
            var TempInput = Input as MemoryStream;
            if (TempInput != null)
            {
                return TempInput.ToArray();
            }
            var Buffer = new byte[1024];
            var ReturnValue = (byte[])null;
            using (var Temp = new MemoryStream())
            {
                while (true)
                {
                    var Count = Input.Read(Buffer, 0, Buffer.Length);
                    if (Count <= 0)
                    {
                        ReturnValue = Temp.ToArray();
                        break;
                    }
                    Temp.Write(Buffer, 0, Count);
                }
            }
            return ReturnValue;
        }
        /// <summary>
        /// 是否为空
        /// </summary>
        /// <param name="value">值</param>
        /// <returns></returns>
        public static bool IsNullOrEmpty(this string value)
        {
            return string.IsNullOrEmpty(value);
        }
        /// <summary>
        /// 将字符转换为指定格式字节数组
        /// </summary>
        /// <param name="Input">input string</param>
        /// <param name="EncodingUsing">The type of encoding the string is using (defaults to UTF8)</param>
        /// <returns>the byte array representing the string</returns>
        public static byte[] ToByteArray(this string Input, Encoding EncodingUsing = null)
        {
            EncodingUsing = Encoding.UTF8;
            return string.IsNullOrEmpty(Input) ? null : EncodingUsing.GetBytes(Input);
        }
        /// <summary>
        /// 对象转换为字节
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="obj">字节</param>
        /// <returns></returns>
        public static byte[] ObjectToBytes(this object obj)
        {
            if (obj.IsNullOrEmpty()) return null;
            try
            {
                using (MemoryStream ms = new MemoryStream())
                {
                    IFormatter formatter = new BinaryFormatter();
                    formatter.Serialize(ms, obj);
                    return ms.GetBuffer();
                }
            }
            catch
            {
                return null;
            }
        }


        /// <summary>
        /// 将字节转换为对象
        /// </summary>
        /// <typeparam name="T">对象</typeparam>
        /// <param name="bytes">字节</param>
        /// <returns></returns>
        public static T ByteToObject<T>(this byte[] bytes)
        {
            if (bytes.IsNullOrEmpty()) return default(T);

            try
            {
                using (MemoryStream ms = new MemoryStream(bytes))
                {
                    IFormatter formatter = new BinaryFormatter();
                    return (T)formatter.Deserialize(ms);
                }
            }
            catch
            {
                return default(T);
            }
        }
    }
}
